﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 库存列表服务
    /// </summary>
    [Route("api/StockList")]
    [ApiDescriptionSettings("库存列表", Name = "StockList", Order = 100)]

    public class StockListService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WareArea, MasterDbContextLocator> _wareAreaRep; //所属库区仓储
        private readonly IRepository<WareLocation, MasterDbContextLocator> _wareLocationRep; //库位仓储
        private readonly IRepository<WareStock, MasterDbContextLocator> _wareStockRep; //库存仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="wareAreaRep"></param>
        /// <param name="wareLocationRep"></param>
        /// <param name="wareStockRep"></param>
        public StockListService(
            IRepository<WareArea, MasterDbContextLocator> wareAreaRep,
            IRepository<WareLocation, MasterDbContextLocator> wareLocationRep,
            IRepository<WareStock, MasterDbContextLocator> wareStockRep
        )
        {
            _wareAreaRep = wareAreaRep;
            _wareLocationRep = wareLocationRep;
            _wareStockRep = wareStockRep;
        }
        #endregion

        /// <summary>
        /// 分页查询库存列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("page")]
        public async Task<PageResult<StockListOutput>> Page([FromQuery] StockListSearch input)
        {
            //获取该库区下的所以库位信息
            var locationList = await _wareLocationRep.Where(input.AreaID != -10, p => p.AreaID == input.AreaID).Select(n => n.Code).ToListAsync();
            var list = await _wareStockRep.DetachedEntities
              .Where(z => z.StockQuantity > new decimal(0.00))
              .Where(input.StockCircle != StockCircleEnum.ALL, u => u.StockCircle == input.StockCircle)
              .Where(!string.IsNullOrEmpty(input.ContainerCode), u => EF.Functions.Like(u.ContainerCode, $"%{input.ContainerCode.Trim()}%"))
              .Where(!string.IsNullOrEmpty(input.LocationCode), u => EF.Functions.Like(u.LocationCode, $"%{input.LocationCode.Trim()}%"))
              .Where(!string.IsNullOrEmpty(input.ProjectCode), u => EF.Functions.Like(u.ProjectCode, $"%{input.ProjectCode.Trim()}%"))
              .Where(!string.IsNullOrEmpty(input.Code), u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%"))
              .Where(!string.IsNullOrEmpty(input.Name), u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%"))
              .Where(!string.IsNullOrEmpty(input.SpecificationModel), u => EF.Functions.Like(u.SpecificationModel, $"%{input.SpecificationModel.Trim()}%"))
              .Where(!string.IsNullOrEmpty(input.LocationCode), u => locationList.Contains(u.LocationCode))
              .Where(!string.IsNullOrEmpty(input.SearchBeginTime), u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
               u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
              .OrderBy(PageInputOrder.OrderBuilder<StockListSearch>(input))
              .ProjectToType<StockListOutput>()
              .ToADPagedListAsync(input.PageNo, input.PageSize);

            foreach (var item in list.Rows)
            {
                var wareLocation = await _wareLocationRep.FirstOrDefaultAsync(z => z.Code == item.LocationCode);
                if (wareLocation == null)
                {
                    item.OriginalLocationCode = "";
                    item.ReservoirArea = "";
                }
                else
                {
                    item.OriginalLocationCode = wareLocation.OriginalLocationCode;

                    // 查询所属库区
                    var wareArea = await _wareAreaRep.FirstOrDefaultAsync(z => z.Id == wareLocation.AreaID);
                    item.ReservoirArea = wareArea != null ? wareArea.AreaName : "";
                }

                item.BrandName = string.IsNullOrEmpty(item.BrandName) || item.BrandName == "无" ? "" : item.BrandName;
                if (item.StockCircle == StockCircleEnum.RED) item.StockCircleName = "红";
                else if (item.StockCircle == StockCircleEnum.YELLOW) item.StockCircleName = "黄";
                else item.StockCircleName = "绿";
            }

            return list;
        }

        /// <summary>
        /// 更新物料库存周期
        /// </summary>
        /// <returns></returns>
        [HttpPost("InventoryAttribute")]
        [UnitOfWork]
        public async Task InventoryAttribute([FromBody] EditStockCircleInput input)
        {
            var model = await _wareStockRep.FirstOrDefaultAsync(e => e.Id == input.Id);
            if (model == null) throw Oops.Oh("数据不存在!");

            model.StockCircle = input.StockCircle;
            await _wareStockRep.UpdateAsync(model);
        }

        ///<summary>
        /// 库存到期时间下拉框
        /// </summary>
        /// <returns></returns>
        [HttpGet("DateList")]
        public List<string> DateList()
        {
            var DateMode = new List<string>();
            DateMode.Add("一个月");
            DateMode.Add("两个月");
            DateMode.Add("三个月");
            DateMode.Add("半年");
            DateMode.Add("一年");
            DateMode.Add("两年");
            DateMode.Add("三年");
            DateMode.Add("五年");
            return DateMode;
        }

        /// <summary>
        /// 更新物料库存到期时间
        /// </summary>
        /// <returns></returns>
        [HttpPost("UpdateDateTime")]
        [UnitOfWork]
        public async Task UpdateDateInput([FromBody] UpdateDateInput input)
        {
            var model = await _wareStockRep.FirstOrDefaultAsync(e => e.Id == input.Id);
            if (model == null) throw Oops.Oh("数据不存在!");

            if (input.StockDate == "一个月") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddMonths(1); }
            else if (input.StockDate == "两个月") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddMonths(2); }
            else if (input.StockDate == "三个月") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddMonths(3); }
            else if (input.StockDate == "半年") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddMonths(6); }
            else if (input.StockDate == "一年") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddYears(1); }
            else if (input.StockDate == "两年") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddYears(2); }
            else if (input.StockDate == "三年") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddYears(3); }
            else if (input.StockDate == "五年") { model.ExpirationTime = Convert.ToDateTime(model.CreatedTime).AddYears(5); }

            await _wareStockRep.UpdateAsync(model);
        }
    }
}
